//  @ Project : GagalPanen
//  @ File Name : plants.cpp
//  @ Date : 3/9/2011
//  @ Author : Irvan
//
//
#include <assert.h>
#include <algorithm>
#include "plants.hpp"
#include "plantablecell.hpp"

Plants::Plants(GameInterface* game) : game_(game), plants_() {
}

Plants::Plants(GameInterface* game, std::ifstream& is) : game_(game), plants_() {
  int n;
  is >> n;

  for (int i = 0; i < n; ++i) {
    plants_.push_back(new Plant(game, is));
  }
}

void Plants::save(std::ofstream& os) {
  os << plants_.size() << std::endl;

  for (int i = 0; i < (int)plants_.size(); ++i) {
    plants_[i]->save(os);
  }
}

Plants::~Plants() {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    delete plants_[i];
  }
}

void Plants::advanceDay() {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    plants_[i]->advanceDay();
  }
  return;
}

void Plants::advanceTime() {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    plants_[i]->advanceTime();
  }
  return;
}

bool Plants::containsPlantAt(Cell* cell) {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    if (plants_[i]->getCell() == cell) {
      return true;
    }
  }
  return false;
}

void Plants::addPlant(Plant* plant) {
  assert(!containsPlantAt(plant->getCell()));
  plants_.push_back(plant);
}

Plant* Plants::getPlantAt(Cell* cell) {
  assert(containsPlantAt(cell));
  for (int i = 0; i < (int)plants_.size(); ++i) {
    if (plants_[i]->getCell() == cell) return plants_[i];
  }
  assert(false);
}

void Plants::removePlant(Plant* plant) {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    if (plants_[i] == plant) {
      PlantableCell* pc = (PlantableCell* )(
              plants_[i]->getCell());
      pc->unplow();
      delete plants_[i];
      plants_.erase(plants_.begin() + i);
      return;
    }
  }
  assert(false);
}

void Plants::makeAllDead() {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    plants_[i]->makeDead();
  }
}

void Plants::restartAllNotDeadToSeed() {
  for (int i = 0; i < (int)plants_.size(); ++i) {
    if (plants_[i]->isDead()) {
      continue;
    }
    plants_[i]->restartToSeed();
  }
}

void Plants::transmutateOneRandomPlant(int new_plant_id) {
  if ((int)plants_.size() == 0) {
    // nothing happens
  } else {
    int rand_id = rand() % (int)plants_.size();
    Cell* prev_cell = plants_[rand_id]->getCell();
    delete plants_[rand_id];
    plants_[rand_id] = new Plant(game_, (PlantableCell*) prev_cell, new_plant_id);
  }
}
